<?php
class ViseminWizard_Controller extends WizardController {

    public $currencyCodeList = array('CZK');

    public function __construct() {
        parent::__construct(
                'ViseminWizardData', /* data class name */
                '/admin/viseminWizard', /* wizardPath */
                'admin/seminarWizardLayout', /* contentLayout */
                ViseminWizardData::$STEPS
        );
        $this->pageTemplate = 'admin/adminTemplate';
    }

    /* ------------------------------------------------------------------- */
    /* - Seminar                                                         - */
    /* ------------------------------------------------------------------- */
    
    protected function viSeminarStep() {
        $this->viSeminarData();

        $viSeminar = array();
        if ($this->data->viSeminar) {
            $viSeminar = $this->data->viSeminar;
        }
        else {
            // Default values
            $viSeminar['last_meal_in_package_option'] = sql::$TRUE;
            $viSeminar['meals_optional'] = sql::$TRUE;
            $viSeminar['cash_payment_available'] = sql::$FALSE;

            if (! valid::isSqlBoolean($this->data->viSeminar['active'])) {
                $viSeminar['active'] = sql::$FALSE;
            }
        }

        $this->viewData['viSeminar'] = $viSeminar;
    }
    
    protected function viSeminarData() {
    	// Select only bank accounts of the local organization
        $this->viewData['bankAccountOptions'] = $this->dao->queryOptions(
                'SELECT id, name FROM bank_account WHERE organization_id = :orgId AND enabled = :enabled ORDER BY name ASC',
                array(
                		'orgId' => Kohana::config('yosemin.viSeminarOrganizationId'),
                		'enabled' => sql::$TRUE)
        		);

        $this->viewData['viAccomodationTypeOptions'] = $this->dao->queryOptions(
                'SELECT code, name, description FROM vi_accomodation_type');

        $this->viewData['viSeminarTagOptions'] = $this->dao->queryOptions(
                'SELECT id, name, description FROM vi_seminar_tag');
    }
    
    protected function viSeminarNext() {
        $viSeminar = $this->postToDbValues();
        $this->viewData['viSeminar'] = $viSeminar;

        // Validation
        $validator = new EntityValidator($viSeminar, 'viSeminar', $this->msg);
        $validator->required('name');
        $validator->required('instructor');
        $validator->date('begin_date');
        $validator->time('begin_time');
        $validator->date('end_date');
        $validator->time('end_time');
        $validator->required('bank_account_id');
        $validator->required('variable_symbol');
        $validator->required('description');
        $validator->required('vi_accomodation_type_codes');
        $validator->booleanOrNull('active');
        $validator->boolean('last_meal_in_package_option');

        if (! $this->msg->hasErrors()) {
            // If we have all required fields, compare the beginning and end dateTimes.
            if (date::diffDateTimes($viSeminar['begin_date'], $viSeminar['begin_time'],
                    $viSeminar['end_date'], $viSeminar['end_time']) <= 0) {
                $this->msg->error('viseminWizard.error-viSeminarBeginsAfterEnd');
            }

            // Unique variable symbol
            if ($this->dao->alreadyExists('vi_seminar', 'variable_symbol', $viSeminar)) {
                $this->msg->error('viseminWizard.error-variableSymbolAlreadyUsed');
            }
        }
        
        if ($this->msg->hasErrors()) {
            return FALSE;
        }

        // Load the selected accomodation types
        $this->data->viAccomodationTypeList = $this->dao->findByCodes('vi_accomodation_type',
                $viSeminar['vi_accomodation_type_codes']);

        $this->data->viSeminar = $viSeminar;
    }

    public function viSeminarFormBuilder() {
    }

    /* ------------------------------------------------------------------- */
    /* - Prices                                                          - */
    /* ------------------------------------------------------------------- */

    protected function pricesStep() {
        $pricesForm = array();
        if ($this->data->pricesForm) {
            $pricesForm = $this->data->pricesForm;
        }
        else {
            // Default values
            $pricesForm['euroPaymentAvailable'] = sql::$FALSE;
            foreach ($this->currencyCodeList as $currencyCode) {
                $pricesForm['viAccomodationTypePrice' . $currencyCode] = array();
                foreach ($this->data->viAccomodationTypeList as $viAccomodationType) {
                    $lastUsage = $this->dao->queryOne(
                            'SELECT * FROM vi_seminar_accomodation_type_price ' .
                            'WHERE vi_accomodation_type_code = :acc_code ' .
                            'AND currency_code = :currency_code ' .
                            'ORDER BY vi_seminar_id DESC LIMIT 1',
                            array(
                                'acc_code' => $viAccomodationType['code'],
                                'currency_code' => $currencyCode
                            ));
                    if ($lastUsage) {
                        $pricesForm['viAccomodationTypePrice' . $currencyCode][$viAccomodationType['code']] = $lastUsage['price'];
                    }
                }
            }

            $startingHour = date::getHour($this->data->viSeminar['begin_time']);
            if ($startingHour <= 9) {
                $pricesForm['first_meal'] = 'breakfast';
            }
            else if ($startingHour <= 12) {
                $pricesForm['first_meal'] = 'lunch';
            }
            else {
                $pricesForm['first_meal'] = 'dinner';
            }

            $endingHour = date::getHour($this->data->viSeminar['end_time']);
            if ($endingHour < 12) {
                $pricesForm['last_meal'] = 'breakfast';
            }
            else if ($endingHour < 17) {
                $pricesForm['last_meal'] = 'lunch';
            }
            else {
                $pricesForm['last_meal'] = 'dinner';
            }

            foreach ($this->currencyCodeList as $currencyCode) {
                $lastSeminar = $this->dao->queryOne(
                        'SELECT * FROM vi_seminar_price ' .
                        'WHERE currency_code = :currency_code ' .
                        'ORDER BY vi_seminar_id DESC LIMIT 1',
                        array('currency_code' => $currencyCode));
                if ($lastSeminar) {
                    $pricesForm[$currencyCode] = array();
                    // Copy meal prices from the last seminar
                    foreach (registrationHelper::$MEAL_LIST as $meal) {
                        $this->copyProperty($lastSeminar, $pricesForm[$currencyCode], $meal . '_price');
                    }

                    // Copy course_fee
                    $this->copyProperty($lastSeminar, $pricesForm[$currencyCode], 'course_fee');

                    // Copy social discount
                    $this->copyProperty($lastSeminar, $pricesForm[$currencyCode], 'social_discount');
                }
            }
        }
        $this->viewData['pricesForm'] = $pricesForm;
        $this->pricesData();
    }

    protected function pricesData() {
        $this->viewData['mealOptions'] = array(
            'breakfast' => text::get('viSeminar.breakfast'),
            'lunch' => text::get('viSeminar.lunch'),
            'dinner' => text::get('viSeminar.dinner')
        );
    }

    protected function pricesNext() {
        $pricesForm = $this->postToDbValues();
        $this->viewData['pricesForm'] = $pricesForm;

        // Validation
        foreach ($this->currencyCodeList as $currencyCode) {
            $validator = new EntityValidator($pricesForm[$currencyCode], 'viSeminar', $this->msg);
            $validator->decimal('course_fee');
            $validator->decimal('bank_payment_discount');
            $validator->decimalOrNull('early_discount');
            if ($pricesForm[$currencyCode]['early_discount']) {
            	$validator2 = new EntityValidator($pricesForm, 'viSeminar');
            	$validator2->date('early_discount_deadline');
            }
            else {
            	unset($pricesForm['early_discount_deadline']);
            }
            $validator->decimal('breakfast_price');
            $validator->decimal('lunch_price');
            $validator->decimal('dinner_price');
            $validator->decimalOrNull('social_discount');
        }
        
        if (! $this->msg->hasErrors()) {
            foreach ($this->currencyCodeList as $currencyCode) {
                foreach ($this->data->viAccomodationTypeList as $viAccomodationType) {
                    $price = $pricesForm['viAccomodationTypePrice' . $currencyCode][$viAccomodationType['code']];
                    if (valid::isWhite($price)) {
                        $this->msg->error('viseminWizard.error-atMissingPrice', text::get('currency.mark-' . $currencyCode), $viAccomodationType['name']);
                    }
                }
                if (! $this->msg->hasErrors()) {
                    foreach ($this->data->viAccomodationTypeList as $viAccomodationType) {
                        $price = $pricesForm['viAccomodationTypePrice' . $currencyCode][$viAccomodationType['code']];
                        if (! valid::isPositiveDecimalOrZero($price)) {
                            $this->msg->error('viseminWizard.error-atPriceNotDecimal', $viAccomodationType['name'], text::get('currency.mark-' . $currencyCode));
                        }
                    }
                }
            }
        }
        if ($this->msg->hasErrors()) {
            return FALSE;
        }
        $this->data->pricesForm = $pricesForm;
    }

    public function savePriceForm() {
        $this->data->pricesForm = $this->postToDbValues();
        $this->redirect($this->stepUrl);
    }

    /* ------------------------------------------------------------------- */
    /* - Summary                                                         - */
    /* ------------------------------------------------------------------- */

    protected function summaryStep() {
        $this->summaryData();
    }

    protected function summaryData() {
        $this->viewData['viSeminar'] = $this->data->viSeminar;
        $this->viSeminarData();

        $this->viewData['pricesForm'] = $this->data->pricesForm;
        $this->pricesData();
    }

    protected function summaryNext() {
    }

    /* ------------------------------------------------------------------- */
    /* - Finish                                                          - */
    /* ------------------------------------------------------------------- */

    private function copyProperty(&$source, &$destination, $property) {
        if ($source[$property]) {
            $destination[$property] = $source[$property];
        }
        else {
            unset($destination[$property]);
        }
    }

    public function finish() {
        $this->dao->getDb()->beginTransaction();
        try {
            // Construct and save the viSeminar
            $this->data->viSeminar['first_meal'] = $this->data->pricesForm['first_meal'];
            $this->data->viSeminar['last_meal'] = $this->data->pricesForm['last_meal'];
            $this->data->viSeminar['night_count'] = date::diffDates($this->data->viSeminar['begin_date'], $this->data->viSeminar['end_date']);
            $this->data->viSeminar['early_discount_deadline'] = $this->data->pricesForm['early_discount_deadline'];
            $viSeminarId = $this->dao->insert('vi_seminar', $this->data->viSeminar, array('vi_accomodation_type_codes', 'vi_seminar_tag_ids', 'undefined'));

            // Insert seminar tags
            if ($this->data->viSeminar['vi_seminar_tag_ids']) {
                foreach ($this->data->viSeminar['vi_seminar_tag_ids'] as $viSeminarTagId) {
                    $viSeminarTagAsoc = array(
                        'vi_seminar_id' => $viSeminarId,
                        'vi_seminar_tag_id' => $viSeminarTagId
                    );
                    $this->dao->insert('vi_seminar_tag_asoc', $viSeminarTagAsoc);
                }
            }

            // Insert prices
            foreach ($this->currencyCodeList as $currencyCode) {
                $this->data->pricesForm[$currencyCode]['currency_code'] = $currencyCode;
                $this->data->pricesForm[$currencyCode]['vi_seminar_id'] = $viSeminarId;
                if (! $this->data->pricesForm[$currencyCode]['social_discount']) {
                    unset($this->data->pricesForm[$currencyCode]['social_discount']);
                }
                
                $this->dao->insert('vi_seminar_price', $this->data->pricesForm[$currencyCode]);
                
            }

            // Save the accomodation types and the prices
            foreach ($this->data->viAccomodationTypeList as $atCode => $viAccomodationType) {
                $viSeminarAccomodationType = array(
                    'vi_seminar_id' => $viSeminarId,
                    'vi_accomodation_type_code' => $atCode
                );
                $this->dao->insert('vi_seminar_accomodation_type', $viSeminarAccomodationType);

                // Insert accomodation type prices
                foreach ($this->currencyCodeList as $currencyCode) {
                    $atPriceCzk = $this->data->pricesForm['viAccomodationTypePrice' . $currencyCode][$atCode];
                    $atPrice = array(
                        'vi_seminar_id' => $viSeminarId,
                        'vi_accomodation_type_code' => $atCode,
                        'currency_code' => $currencyCode,
                        'price' => $atPriceCzk
                    );
                    $this->dao->insert('vi_seminar_accomodation_type_price', $atPrice);
                }
            }

            $this->dao->getDb()->commit();
        }
        catch (Exception $e) {
            // If something raised an exception in our transaction block of statements,
            // roll back any work performed in the transaction
            $this->dao->getDb()->rollBack();

            // Recoverable: vi_seminar_name_date_unq constraint violated ...
            if (strpos($e->getMessage(), 'vi_seminar_name_date_unq')) {
                $this->msg->error('viregWizard.error-alreadyExists', $this->data->viSeminar['name']);
                $this->redirect($this->stepUrl);
            }
            // Recoverable: vi_seminar_var_symbol_unq constraint violated ...
            if (strpos($e->getMessage(), 'vi_seminar_var_symbol_unq')) {
                $this->msg->error('viseminWizard.error-variableSymbolAlreadyUsed');
                $this->redirect($this->stepUrl);
            }

            // Clear the wizard data
            // $this->clearData();

            throw $e;
        }

        $this->clearData();
        $this->redirect('/admin/viseminWizard/success?id=' . $viSeminarId);
    }

    public function success() {
        $viSeminarId = $this->input->get('id');
        $this->contentLayout = 'admin/adminLayout';
        $this->renderSubview('admin/viseminWizard/wizardSuccess');
    }
}
?>